package dao;

import application.exceptions.ItemNotFoundException;
import mappings.Appliances;
import mappings.AppliancesComposition;
import mappings.Material;
import mappings.Standards;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import utils.HibernateUtil;

import java.util.List;

public class AppliancesCompositionDao
{
    private static SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

    public List<AppliancesComposition> getAppliancesCompositionsForMaterial(int materialId)
    {
        Session session = sessionFactory.openSession();

        List<AppliancesComposition> appliancesCompositions = session.createCriteria(AppliancesComposition.class)
                .add(Restrictions.eq("material.id", materialId))
                .list();

        session.close();

        return appliancesCompositions;
    }

    /*
     * Zwraca appliances_compositions dla zadanej pary material/standard
     */
    public List<AppliancesComposition> getAppliancesCompositionForMaterialAndStandard(Material material, Standards standard)
    {
        Session session = sessionFactory.openSession();

        List<AppliancesComposition> appliancesCompositions = session.createCriteria(AppliancesComposition.class)
                .add(Restrictions.eq("standards", standard))
                .add(Restrictions.eq("material", material))
                .list();

        session.close();

        return appliancesCompositions;
    }

    public AppliancesComposition addProducentComposition(int materialId, int standardId, int applianceId) throws ItemNotFoundException
    {
        AppliancesComposition appliancesComposition = new AppliancesComposition();

        org.hibernate.classic.Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();

        Material material = (Material) session.get(Material.class, materialId);
        Standards standard = (Standards) session.get(Standards.class, standardId);
        Appliances appliance = (Appliances) session.get(Appliances.class, applianceId);

        if(material == null || standard == null || appliance == null)
        {
            tx.rollback();
            session.close();
            throw new ItemNotFoundException();
        }

        appliancesComposition.setMaterial(material);
        appliancesComposition.setStandards(standard);
        appliancesComposition.setAppliances(appliance);

        session.save(appliancesComposition);

        tx.commit();
        session.close();

        return appliancesComposition;
    }

    public void deleteApplianceComposition(Integer id) throws ItemNotFoundException
    {
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();

        int affectedRows = session.createQuery("delete AppliancesComposition where id = :id")
                .setParameter("id", id)
                .executeUpdate();

        if(affectedRows == 0)
        {
            tx.rollback();
            session.close();
            throw new ItemNotFoundException();
        }

        tx.commit();
        session.close();
    }

    public AppliancesComposition editProducentComposition(Integer id, int materialId, int standardId, int applianceId) throws ItemNotFoundException
    {
        org.hibernate.classic.Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();

        AppliancesComposition appliancesComposition = (AppliancesComposition) session.get(AppliancesComposition.class, id);
        Material material = (Material) session.get(Material.class, materialId);
        Standards standard = (Standards) session.get(Standards.class, standardId);
        Appliances appliance = (Appliances) session.get(Appliances.class, applianceId);

        if(material == null || standard == null || appliance == null)
        {
            tx.rollback();
            session.close();
            throw new ItemNotFoundException();
        }

        appliancesComposition.setMaterial(material);
        appliancesComposition.setAppliances(appliance);
        appliancesComposition.setStandards(standard);
        session.update(appliancesComposition);
        tx.commit();
        session.close();

        return appliancesComposition;
    }
}
